package com.yehebl.orm.data.mysql;

import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import java.util.Map.Entry;

import com.yehebl.orm.dto.ClassInfo;
import com.yehebl.orm.dto.FieldInfo;
import com.yehebl.orm.manager.ReadClassManager;


/**
 * sql 语句初始化或者生成新的sql 语句
 */
public class MySqlSqlManager {
	private static final Map<String, String> map = new HashMap<>();
	private static final String insert = "_insert";
	private static final String update = "_update";
	private static final String delete = "_delete";
	private static final String select = "_select";
	// 带表名，返回java属性
	private static final String column = "_column";
	// 原生表字段
	private static final String column_no_as = "_column_no_as";
	// 带表别名，返回字段java属性
	private static final String column_as = "_column_as_";
	// 带别名带返回对象属性名 返回字段java属性
	private static final String column_object_name_as_ = "_column_object_name_as_";
	private static final String id_where = "_id_where";

	/**
	 * 获取插入sql
	 */
	public static String getInsert(ClassInfo ci) {
		if (map.containsKey(ci.getClazz().getName() + insert)) {
			return map.get(ci.getClazz().getName() + insert);
		}
		StringBuilder sb = new StringBuilder();
		sb.append("insert into `").append(ci.getTableName()).append("` (").append(getColumnNoAs(ci)).append(")values(").append(getValuesParams(ci.getTableFieldMap().size())).append(")");
		map.put(ci.getClazz().getName() + insert, sb.toString());
		return sb.toString();
	}

	/**
	 * 获取更新语句
	 */
	public static String getUpdate(ClassInfo ci) {
		if (map.containsKey(ci.getClazz().getName() + update)) {
			return map.get(ci.getClazz().getName() + update);
		}
		StringBuilder sb = new StringBuilder();
		sb.append("update `").append(ci.getTableName()).append("` set ");
		Map<String, FieldInfo> tableFieldMap = ci.getTableFieldMap();
		for (String tableName : tableFieldMap.keySet()) {
			sb.append("`").append(tableName).append("`=?,");
		}
		sb.delete(sb.length() - 1, sb.length());
		map.put(ci.getClazz().getName() + update, sb.toString());
		return sb.toString();
	}

	/**
	 * 获取更新部分属性语句
	 */
	public static String getUpdate(ClassInfo ci, Set<String> acceptSet) {
		if (acceptSet.size() == 0) {
			return getUpdate(ci);
		}
		StringBuilder sb = new StringBuilder();
		sb.append("update `").append(ci.getTableName()).append("` set ");
		for (Entry<String, FieldInfo> entry : ci.getTableFieldMap().entrySet()) {
			if (!acceptSet.contains(entry.getValue().getFieldName())) {
				continue;
			}
			sb.append("`").append(entry.getKey()).append("`=?,");
		}
		sb.delete(sb.length() - 1, sb.length());
		return sb.toString();
	}

	/**
	 * 获取更新部分属性语句
	 * 
	 */
	public static String getUpdateFilter(ClassInfo ci, Set<String> filterSet) {
		if (filterSet==null||filterSet.size() == 0) {
			return getUpdate(ci);
		}
		StringBuilder sb = new StringBuilder();
		sb.append("update `").append(ci.getTableName()).append("` set ");
		for (Entry<String, FieldInfo> entry : ci.getTableFieldMap().entrySet()) {
			if (filterSet.contains(entry.getValue().getFieldName())) {
				continue;
			}
			sb.append("`").append(entry.getKey()).append("`=?,");
		}
		sb.delete(sb.length() - 1, sb.length());
		return sb.toString();
	}

	/**
	 * 获取删除语句
	 */
	public static String getDelete(ClassInfo ci) {
		if (map.containsKey(ci.getClazz().getName() + delete)) {
			return map.get(ci.getClazz().getName() + delete);
		}
		StringBuilder sb = new StringBuilder();
		sb.append("delete from `").append(ci.getTableName()).append("`");
		map.put(ci.getClazz().getName() + delete, sb.toString());
		return sb.toString();
	}

	/**
	 * 获取查询语句
	 */
	public static String getSelect(ClassInfo ci) {
		if (map.containsKey(ci.getClazz().getName() + select)) {
			return map.get(ci.getClazz().getName() + select);
		}
		StringBuilder sb = new StringBuilder();
		sb.append("select ").append(getColumn(ci)).append(" from `").append(ci.getTableName()).append("`");
		map.put(ci.getClazz().getName() + select, sb.toString());
		return sb.toString();
	}

	public static String getSelect(Class<?> clazz) {
		ClassInfo classInfo = ReadClassManager.map.get(clazz.getName());
		return getSelect(classInfo);
	}

	private static String getValuesParams(int length) {
		StringBuilder sb = new StringBuilder();
		boolean flag=false;
		for (int i = 0; i < length; i++) {
			if(!flag) {
				sb.append("?");
				flag=true;
				continue;
			}
			sb.append(",?");
		}
		return sb.toString();
	}

	/**
	 * 获取列名逗号分隔
	 */
	public static String getColumn(ClassInfo ci) {
		if (map.containsKey(ci.getClazz().getName() + column)) {
			return map.get(ci.getClazz().getName() + column);
		}
		Map<String, FieldInfo> tableFieldMap = ci.getTableFieldMap();
		StringBuilder sb = new StringBuilder();
		boolean flag = false;
		for (String tableName : tableFieldMap.keySet()) {
			if (!flag) {
				sb.append("`").append(tableName).append("` `").append(tableFieldMap.get(tableName).getFieldName()).append("`");
				flag = true;
				continue;
			}
			sb.append(",`").append(tableName).append("` `").append(tableFieldMap.get(tableName).getFieldName()).append("`");
		}
		map.put(ci.getClazz().getName() + column, sb.toString());
		return sb.toString();
	}

	/**
	 * 获取列名逗号分隔
	 */
	public static String getColumn(ClassInfo ci, String tableAs) {
		if (map.containsKey(ci.getClazz().getName() + column_as + tableAs)) {
			return map.get(ci.getClazz().getName() + column_as + tableAs);
		}
		Map<String, FieldInfo> tableFieldMap = ci.getTableFieldMap();
		StringBuilder sb = new StringBuilder();
		boolean flag = false;
		for (String tableName : tableFieldMap.keySet()) {
			if (!flag) {
				sb.append(tableAs).append(".`").append(tableName).append("` `").append(tableFieldMap.get(tableName).getFieldName()).append("`");
				flag = true;
				continue;
			}
			sb.append(",").append(tableAs).append(".`").append(tableName).append("` `").append(tableFieldMap.get(tableName).getFieldName()).append("`");
		}
		map.put(ci.getClazz().getName() + column_as, sb.toString());
		return sb.toString();
	}

	/**
	 * 获取列名逗号分隔,有别名有属性名
	 * @param tableAs 表别名
	 */
	public static String getColumn(ClassInfo ci, String tableAs, String objectName) {
		if (map.containsKey(ci.getClazz().getName() + column_object_name_as_ + tableAs)) {
			return map.get(ci.getClazz().getName() + column_object_name_as_ + tableAs);
		}
		Map<String, FieldInfo> tableFieldMap = ci.getTableFieldMap();
		StringBuilder sb = new StringBuilder();
		boolean flag = false;
		for (String tableName : tableFieldMap.keySet()) {
			if (!flag) {
				sb.append(tableAs).append(".`").append(tableName).append("` `").append(objectName).append(".").append(tableFieldMap.get(tableName).getFieldName()).append("`");
				flag = true;
				continue;
			}
			sb.append(",").append(tableAs).append(".`").append(tableName).append("` `").append(objectName).append(".").append(tableFieldMap.get(tableName).getFieldName()).append("`");
		}
		map.put(ci.getClazz().getName() + column_object_name_as_, sb.toString());
		return sb.toString();
	}

	/**
	 * 获取没有别名的列名逗号分隔
	 */
	public static String getColumnNoAs(ClassInfo ci) {
		if (map.containsKey(ci.getClazz().getName() + column_no_as)) {
			return map.get(ci.getClazz().getName() + column_no_as);
		}
		Map<String, FieldInfo> tableFieldMap = ci.getTableFieldMap();
		StringBuilder sb = new StringBuilder();
		boolean flag = false;
		for (String tableName : tableFieldMap.keySet()) {
			if (!flag) {
				sb.append("`").append(tableName).append("` ");
				flag = true;
				continue;
			}
			sb.append(",`").append(tableName).append("` ");
		}
		map.put(ci.getClazz().getName() + column_no_as, sb.toString());
		return sb.toString();
	}

	/**
	 * 初始化sql语句
	 */
	public static void initSql(ClassInfo ci) {
		getColumn(ci);
		getSelect(ci);
		getInsert(ci);
		getDelete(ci);
		getUpdate(ci);
		getIdWhere(ci);
	}

	public static String getIdWhere(ClassInfo ci) {
		if (map.containsKey(ci.getClazz().getName() + id_where)) {
			return map.get(ci.getClazz().getName() + id_where);
		}
		StringBuilder sb = new StringBuilder();
		boolean flag = false;
		for (FieldInfo fi : ci.getIdFieldInfo()) {
			if (!flag) {
				sb.append(" where `").append(fi.getTableFieldName()).append("`=?");
				flag = true;
				continue;
			}
			sb.append(" and `").append(fi.getTableFieldName()).append("`=?");

		}
		map.put(ci.getClazz().getName() + id_where, sb.toString());
		return sb.toString();
	}
}
